package com.liuweiheng.base.utils;

import cn.hutool.json.JSONUtil;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
import springfox.documentation.spring.web.json.Json;

import java.util.Collection;
import java.util.concurrent.TimeUnit;

/**
 * Redis api工具类
 *
 * @author lwh
 */
@Component
public class GlobalStrRedisUtil {

    private static final StringRedisTemplate template;

    static {
        template = (StringRedisTemplate) ApplicationContextUtil.getBean("stringRedisTemplate");
    }


    public static final long DEFAULT_EXPIRE = 864000L;
    public static final long NOT_EXPIRE = -1L;

    /**
     * 检查是否存在key
     */
    public static boolean hasKey(final String key) {
        if (StringUtils.isEmpty(key)) {
           throw new RuntimeException("查询缓存key不应该为空");
        }

        return Boolean.TRUE.equals(template.hasKey(key));
    }

    // =========================== 事务 ======================================

    /**
     * 开启事务
     */
    public static void begin() {
        // 开启Redis事务权限
        template.setEnableTransactionSupport(true);
        // 开启事务
        template.multi();
    }

    /**
     * 提交事务
     */
    public static void commit() {
        template.exec();
    }

    /**
     * 回滚事务
     */
    public static void fallback() {
        template.discard();
    }

    // =========================== string类型 ======================================

    /**
     * 设置值
     */
    public static void setValue(final String key, final String value) {
        template.opsForValue().set(key, value, DEFAULT_EXPIRE, TimeUnit.SECONDS);
    }


    public static void setValue(final String key, final String value, final long expire) {
        if (expire > 0) {
            template.opsForValue().set(key, value, expire, TimeUnit.SECONDS);
        } else {
            setValue(key, value);
        }
    }


    public static void setValue(final String key, final String value, final long expire, TimeUnit timeUnit) {
        template.opsForValue().set(key, value, expire, timeUnit);
    }

    /**
     * 获取key
     */
    public static String getValue(final String key) {
        return template.opsForValue().get(key);
    }

    /**
     * 删除key
     */
    public static boolean delKey(final String key) {
        return Boolean.TRUE.equals(template.delete(key));
    }

    /**
     * 批量删除key
     * @param keys keys
     * @return 删除成功数量
     */
    public static Long delKey(final Collection<String> keys) {
        return template.delete(keys);
    }

    // =========================== hash类型 ======================================

    /**
     * 存储HASH类型数据
     *
     * @param hashKey hashKey
     * @param key 键
     * @param val 值
     */
    public static void setHashVal(final String hashKey, final String key, final Object val) {
        template.opsForHash().put(hashKey, key, JSONUtil.toJsonStr(val));
    }

    /**
     * 获取hash类型数据
     *
     * @param hashKey hashKey
     * @param key 键
     * @return 值
     */
    public static Object getHashVal(final String hashKey, final String key) {
        return template.opsForHash().get(hashKey, key);
    }

    /**
     * 是否存在hash类型 key
     * @param hashKey hashKey
     * @param key 键
     * @return true | false
     */
    public static boolean containHashKey(final String hashKey, final String key) {
        return Boolean.TRUE.equals(template.opsForHash().hasKey(hashKey, key));
    }

    /**
     * 删除hash类型key
     * @param hashKey hashKey
     * @param key 键
     * @return true | false
     */
    public static Long delHashKey(final String hashKey, final String key) {
        return template.opsForHash().delete(hashKey, key);
    }
}
